home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / public / SciAn / src / ScianVisTraces.c < prev    next >
C/C++ Source or Header  |  1994-08-01  |  18KB  |  715 lines

  1. /*ScianVisTraces.c
  2.   Eric Pepke
  3.   September 9, 1991
  4.   Trace visualization object in SciAn
  5. */
  6.  
  7. #include "Scian.h"
  8. #include "ScianTypes.h"
  9. #include "ScianArrays.h"
  10. #include "ScianWindows.h"
  11. #include "ScianTextBoxes.h"
  12. #include "ScianObjWindows.h"
  13. #include "ScianIcons.h"
  14. #include "ScianColors.h"
  15. #include "ScianControls.h"
  16. #include "ScianLists.h"
  17. #include "ScianSpaces.h"
  18. #include "ScianButtons.h"
  19. #include "ScianSliders.h"
  20. #include "ScianIDs.h"
  21. #include "ScianDatasets.h"
  22. #include "ScianErrors.h"
  23. #include "ScianVisObjects.h"
  24. #include "ScianVisWindows.h"
  25. #include "ScianStyle.h"
  26. #include "ScianPictures.h"
  27. #include "ScianTimers.h"
  28.  
  29. #ifndef RELEASE
  30.  
  31. #define NSEGMENTS    10        /*Number of segments in a trace to show*/
  32.  
  33. ObjPtr traceClass;            /*Class for trace*/
  34.  
  35. static ObjPtr MakeTraceBounds(object)
  36. ObjPtr object;
  37. /*Makes bounds for a trace*/
  38. {
  39.     ObjPtr objBounds;
  40.     real bounds[6];
  41.     ObjPtr dataObj;
  42.     ObjPtr var;
  43.     int component;
  44.     long index, *dims;
  45.     real sample;
  46.  
  47.     /*Go through all data expanding bounds*/
  48.     bounds[0] = 1E12;
  49.     bounds[1] = -1E12;
  50.     bounds[2] = 1E12;
  51.     bounds[3] = -1E12;
  52.     bounds[4] = 1E12;
  53.     bounds[5] = -1E12;
  54.  
  55.     /*X bounds*/
  56.     dataObj = GetObjectVar("TraceBounds", object, XFIELD);
  57.     var = GetIntVar("TraceBounds", object, XTOPDIM);
  58.     if (!dataObj || !var)
  59.     {
  60.         return ObjFalse;
  61.     }
  62.     component = GetInt(var);
  63.  
  64.     SetCurField(FIELD1, dataObj);
  65.     if (GetNComponents(FIELD1) < component)
  66.     {
  67.         component = GetNComponents(FIELD1);
  68.     }
  69.  
  70.     if (CountComponentDims(FIELD1, component) != 1)
  71.     {
  72.         ReportError("TraceBounds", "Only one-dimensional components are valid in a trace");
  73.         return ObjFalse;
  74.     }
  75.  
  76.     dims = GetComponentDims(FIELD1, component);
  77.  
  78.     index = 0;
  79.     sample = SelectFieldComponent(FIELD1, component, &index);
  80.     bounds[0] = sample;
  81.     bounds[1] = sample;
  82.     for (index = 1; index < dims[0]; ++index)
  83.     {
  84.         sample = SelectFieldComponent(FIELD1, component, &index);
  85.         if (sample < bounds[0]) bounds[0] = sample;
  86.         if (sample > bounds[1]) bounds[1] = sample;
  87.     }
  88.  
  89.     /*Y bounds*/
  90.     dataObj = GetObjectVar("TraceBounds", object, YFIELD);
  91.     var = GetIntVar("TraceBounds", object, YTOPDIM);
  92.     if (!dataObj || !var)
  93.     {
  94.         return ObjFalse;
  95.     }
  96.     component = GetInt(var);
  97.  
  98.     SetCurField(FIELD1, dataObj);
  99.     if (GetNComponents(FIELD1) < component)
  100.     {
  101.         component = GetNComponents(FIELD1);
  102.         printf("Bumping component down to %d", component);
  103.     }
  104.  
  105.     if (CountComponentDims(FIELD1, component) != 1)
  106.     {
  107.         ReportError("TraceBounds", "Only one-dimensional components are valid in a trace");
  108.         return ObjFalse;
  109.     }
  110.  
  111.     dims = GetComponentDims(FIELD1, component);
  112.  
  113.     index = 0;
  114.     sample = SelectFieldComponent(FIELD1, component, &index);
  115.     bounds[2] = sample;
  116.     bounds[3] = sample;
  117.     for (index = 1; index < dims[0]; ++index)
  118.     {
  119.         sample = SelectFieldComponent(FIELD1, component, &index);
  120.         if (sample < bounds[2]) bounds[2] = sample;
  121.         if (sample > bounds[3]) bounds[3] = sample;
  122.     }
  123.  
  124.     /*Z bounds*/
  125.     dataObj = GetObjectVar("TraceBounds", object, ZFIELD);
  126.     var = GetIntVar("TraceBounds", object, ZTOPDIM);
  127.     if (!dataObj || !var)
  128.     {
  129.         return ObjFalse;
  130.     }
  131.     component = GetInt(var);
  132.  
  133.     SetCurField(FIELD1, dataObj);
  134.     if (GetNComponents(FIELD1) < component)
  135.     {
  136.         component = GetNComponents(FIELD1);
  137.     }
  138.  
  139.     if (CountComponentDims(FIELD1, component) != 1)
  140.     {
  141.         ReportError("TraceBounds", "Only one-dimensional components are valid in a trace");
  142.         return ObjFalse;
  143.     }
  144.  
  145.     dims = GetComponentDims(FIELD1, component);
  146.  
  147.     index = 0;
  148.     sample = SelectFieldComponent(FIELD1, component, &index);
  149.     bounds[4] = sample;
  150.     bounds[5] = sample;
  151.     for (index = 0; index < dims[0]; ++index)
  152.     {
  153.         sample = SelectFieldComponent(FIELD1, component, &index);
  154.         if (sample < bounds[4]) bounds[4] = sample;
  155.         if (sample > bounds[5]) bounds[5] = sample;
  156.     }
  157.  
  158.     objBounds = NewRealArray(1, (long) 6);
  159.     CArray2Array(objBounds, bounds);
  160.     SetVar(object, BOUNDS, objBounds);
  161.     return ObjTrue;
  162. }
  163.  
  164. static ObjPtr ChangeMovingTrace(object)
  165. ObjPtr object;
  166. /*Changed value for a moving trace*/
  167. {
  168.     int movingTrace;
  169.     ObjPtr val;
  170.     ObjPtr repObj;
  171.  
  172.     repObj = GetObjectVar("ChangeMovingTrace", object, REPOBJ);
  173.     if (!repObj)
  174.     {
  175.     return ObjFalse;
  176.     }
  177.  
  178.     val = GetVar(object, VALUE);
  179.     if (val)
  180.     {
  181.     movingTrace = GetInt(val);
  182.     }
  183.     else
  184.     {
  185.     movingTrace = false;
  186.     }
  187.  
  188.     DoNotDisturb(repObj, WAKEUP);
  189.     if (movingTrace)
  190.     {
  191.     SetVar(repObj, HILITESEGMENT, NewInt(1));
  192.     WakeMe(repObj, WAKEUP, Clock());
  193.     }
  194.     else
  195.     {
  196.     SetVar(repObj, HILITESEGMENT, NULLOBJ);
  197.     }
  198.     ImInvalid(repObj);
  199.     return ObjTrue;
  200. }
  201.  
  202. static ObjPtr AddTraceControls(object, panelContents)
  203. ObjPtr object, panelContents;
  204. /*Adds controls for a trace object*/
  205. {
  206.     int width;
  207.     int left, top;
  208.     ObjPtr checkBox;
  209.     int smooth;
  210.  
  211.     width = CWINWIDTH - 2 * CORRALBORDER - CWINCORRALWIDTH;
  212.     left = MAJORBORDER;
  213.     top = CWINHEIGHT - MAJORBORDER;
  214. /****UPDATE*** moving trace is not the best idea*/
  215.     /*Create the check box for moving trace*/
  216.     checkBox = NewCheckBox(left, left + width,
  217.     top - CHECKBOXHEIGHT, top, 
  218.     "Moving Trace", GetVar(object, HILITESEGMENT) ? 1 : 0);
  219.     if (!checkBox)
  220.     {
  221.     return ObjFalse;
  222.     }
  223.     PrefixList(panelContents, checkBox);
  224.     SetVar(checkBox, HELPSTRING,
  225.     NewString("If this box is checked, a moving red trace will follow \
  226. the trace through time.\n"));
  227.     SetVar(checkBox, PARENT, panelContents);
  228.     SetVar(checkBox, REPOBJ, object);
  229.     SetMethod(checkBox, CHANGEDVALUE, ChangeMovingTrace);
  230.     top -= CHECKBOXHEIGHT + CHECKBOXSPACING;
  231.  
  232.     /*Create the check box for smooth trace*/
  233.     smooth = GetPredicate(object, SMOOTH);
  234.     checkBox = NewCheckBox(left, left + width,
  235.     top - CHECKBOXHEIGHT, top, "Smooth Trace", smooth);
  236.     if (!GetVar(object, SMOOTH))
  237.     {
  238.     SetVar(object, SMOOTH, NewInt(0));
  239.     }
  240.     if (!checkBox)
  241.     {
  242.     return ObjFalse;
  243.     }
  244.     PrefixList(panelContents, checkBox);
  245.     SetVar(checkBox, HELPSTRING, 
  246.     NewString("If this box is checked, the trace will be drawn smoothly \
  247. using a Cardinal spline.  If not, the trace will be drawn with a series of \
  248. line segments."));
  249.     SetVar(checkBox, PARENT, panelContents);
  250.     AssocDirectControlWithVar(checkBox, object, SMOOTH);
  251.     top -= CHECKBOXHEIGHT + CHECKBOXSPACING;
  252.  
  253.     return ObjTrue;
  254. }
  255.  
  256. static ObjPtr WakeTrace(object)
  257. ObjPtr object;
  258. /*Wakes up a trace*/
  259. {
  260.     ObjPtr space;
  261.     WinInfoPtr window;
  262.     ObjPtr hiliteObj;
  263.     ObjPtr dataField;
  264.     long nSamples;
  265.     int xComponent;
  266.     ObjPtr var;
  267.     long *dims;
  268.     int hiliteSegment;
  269.  
  270.     /*Set up X coordinate*/
  271.     dataField = GetObjectVar("WakeTrace", object, XFIELD);
  272.     var = GetIntVar("WakeTrace", object, XTOPDIM);
  273.     if (!dataField || !var)
  274.     {
  275.     return ObjFalse;
  276.     }
  277.     xComponent = GetInt(var);
  278.  
  279.     SetCurField(FIELD1, dataField);
  280.     if (GetNComponents(FIELD1) < xComponent)
  281.     {
  282.     xComponent = GetNComponents(FIELD1);
  283.     }
  284.  
  285.     if (CountComponentDims(FIELD1, xComponent) != 1)
  286.     {
  287.     ReportError("WakeTrace", "Only one-dimensional components are valid in a trace");
  288.     }
  289.  
  290.     dims = GetComponentDims(FIELD1, xComponent);
  291.     nSamples = *dims;
  292.  
  293.     /*Next highlighted segment*/
  294.     hiliteObj = GetVar(object, HILITESEGMENT);
  295.     if (hiliteObj)
  296.     {
  297.     hiliteSegment = GetInt(hiliteObj);
  298.     hiliteSegment += 1;
  299.     if (hiliteSegment > nSamples)
  300.     {
  301.         SetVar(object, HILITESEGMENT, NewInt(0));
  302.     }
  303.     else
  304.     {
  305.         SetVar(object, HILITESEGMENT, NewInt(hiliteSegment));
  306.     }
  307.     WakeMe(object, WAKEUP, Clock() + 1.0 / 30.0);
  308.     }
  309.  
  310.     ImInvalid(object);
  311.  
  312.     return ObjTrue;
  313. }
  314.  
  315. static ObjPtr SetTraceMainDataset(visObj, dataSet)
  316. ObjPtr visObj, dataSet;
  317. /*Sets the main data set of visObj to dataSet*/
  318. {
  319.     SetVar(visObj, XFIELD, dataSet);
  320.     SetVar(visObj, YFIELD, dataSet);
  321.     SetVar(visObj, ZFIELD, dataSet);
  322.     SetVar(visObj, MAINDATASET, dataSet);
  323.     return ObjTrue;
  324. }
  325.  
  326. static ObjPtr InitTrace(visObj)
  327. ObjPtr visObj;
  328. /*Initializes a trace*/
  329. {
  330.     SetVar(visObj, XTOPDIM, NewInt(0));
  331.     SetVar(visObj, YTOPDIM, NewInt(1));
  332.     SetVar(visObj, ZTOPDIM, NewInt(2));
  333.  
  334.     return ObjTrue;
  335. }
  336.  
  337. static ObjPtr DrawTrace(object)
  338. ObjPtr object;
  339. /*Draw a trace*/
  340. {
  341. #ifdef GRAPHICS
  342.     long k;
  343.     int xComponent, yComponent, zComponent;
  344.     int x, y, z;
  345.     real xScale, yScale, zScale;
  346.     ObjPtr dataField, var;
  347.     Bool smooth;
  348.     long *dims;
  349.     int hiliteSegment;
  350.     Coord curveSeg[4][3];
  351.     long nSamples;        /*The number of samples*/
  352.  
  353.     /*Get x, y, z, scale*/
  354.     var = GetRealVar("DrawTrace", object, XSCALE);
  355.     if (var)
  356.     {
  357.     xScale = GetReal(var);
  358.     }
  359.     else 
  360.     {
  361.     xScale = 1.0;
  362.     }
  363.     var = GetRealVar("DrawTrace", object, YSCALE);
  364.     if (var)
  365.     {
  366.     yScale = GetReal(var);
  367.     }
  368.     else 
  369.     {
  370.     yScale = 1.0;
  371.     }
  372.     var = GetRealVar("DrawTrace", object, ZSCALE);
  373.     if (var)
  374.     {
  375.     zScale = GetReal(var);
  376.     }
  377.     else 
  378.     {
  379.     zScale = 1.0;
  380.     }
  381.  
  382.     /*Set up X coordinate*/
  383.     dataField = GetObjectVar("DrawTrace", object, XFIELD);
  384.     var = GetIntVar("DrawTrace", object, XTOPDIM);
  385.     if (!dataField || !var)
  386.     {
  387.     return ObjFalse;
  388.     }
  389.     xComponent = GetInt(var);
  390.  
  391.     SetCurField(FIELD1, dataField);
  392.     if (GetNComponents(FIELD1) < xComponent)
  393.     {
  394.     xComponent = GetNComponents(FIELD1);
  395.     }
  396.  
  397.     if (CountComponentDims(FIELD1, xComponent) != 1)
  398.     {
  399.     ReportError("DrawTrace", "Only one-dimensional components are valid in a trace");
  400.     }
  401.  
  402.     dims = GetComponentDims(FIELD1, xComponent);
  403.     nSamples = *dims;
  404.  
  405.     /*Set up Y coordinate*/
  406.     dataField = GetObjectVar("DrawTrace", object, YFIELD);
  407.     var = GetIntVar("DrawTrace", object, YTOPDIM);
  408.     if (!dataField || !var)
  409.     {
  410.     return ObjFalse;
  411.     }
  412.     yComponent = GetInt(var);
  413.  
  414.     SetCurField(FIELD2, dataField);
  415.     if (GetNComponents(FIELD2) < yComponent)
  416.     {
  417.     yComponent = GetNComponents(FIELD2);
  418.     }
  419.  
  420.     if (CountComponentDims(FIELD2, yComponent) != 1)
  421.     {
  422.     ReportError("DrawTrace", "Only one-dimensional components are valid in a trace");
  423.     }
  424.  
  425.     dims = GetComponentDims(FIELD2, yComponent);
  426.     if (*dims != nSamples)
  427.     {
  428.     /****UPDATE*** do something else*/
  429.     nSamples = MIN(*dims, nSamples);
  430.     }
  431.  
  432.     /*Set up Z coordinate*/
  433.     dataField = GetObjectVar("DrawTrace", object, ZFIELD);
  434.     var = GetIntVar("DrawTrace", object, ZTOPDIM);
  435.     if (!dataField || !var)
  436.     {
  437.     return ObjFalse;
  438.     }
  439.     zComponent = GetInt(var);
  440.  
  441.     SetCurField(FIELD3, dataField);
  442.     if (GetNComponents(FIELD3) < zComponent)
  443.     {
  444.     zComponent = GetNComponents(FIELD3);
  445.     }
  446.  
  447.     if (CountComponentDims(FIELD3, zComponent) != 1)
  448.     {
  449.     ReportError("DrawTrace", "Only one-dimensional components are valid in a trace");
  450.     }
  451.  
  452.     dims = GetComponentDims(FIELD3, zComponent);
  453.     if (*dims != nSamples)
  454.     {
  455.     /****UPDATE*** do something else*/
  456.     nSamples = MIN(*dims, nSamples);
  457.     }
  458.  
  459.     /*Get smooth predicate*/
  460.     smooth = GetPredicate(object, SMOOTH);
  461.  
  462.     /*Determine which segment to hilite, if any*/
  463.     var = GetVar(object, HILITESEGMENT);
  464.     if (var && IsInt(var))
  465.     {
  466.     hiliteSegment = GetInt(var);
  467.     }
  468.     else
  469.     {
  470.     hiliteSegment = -50;
  471.     }
  472.  
  473.  
  474.     SetLineWidth(1);
  475.  
  476.     /*Make z-buffer read-only*/
  477.     BeginMask(true, true, true, false);
  478.  
  479.     if (smooth)
  480.     {
  481.     int b, e;
  482.     curvebasis(CARDBASIS);
  483.  
  484.     SetUIColor(WHITE);
  485.     /*Draw the unhilited segments*/
  486.     k = 0;
  487.     x = xScale * SelectFieldComponent(FIELD1, xComponent, &k);
  488.     y = yScale * SelectFieldComponent(FIELD2, yComponent, &k);
  489.     z = zScale * SelectFieldComponent(FIELD3, zComponent, &k);
  490.     curveSeg[0][0] = x;
  491.     curveSeg[0][1] = y;
  492.     curveSeg[0][2] = z;
  493.     curveSeg[1][0] = x;
  494.     curveSeg[1][1] = y;
  495.     curveSeg[1][2] = z;
  496.  
  497.     k = 1;
  498.     x = xScale * SelectFieldComponent(FIELD1, xComponent, &k);
  499.     y = yScale * SelectFieldComponent(FIELD2, yComponent, &k);
  500.     z = zScale * SelectFieldComponent(FIELD3, zComponent, &k);
  501.     curveSeg[2][0] = x;
  502.     curveSeg[2][1] = y;
  503.     curveSeg[2][2] = z;
  504.  
  505.     k = 2;
  506.     x = xScale * SelectFieldComponent(FIELD1, xComponent, &k);
  507.     y = yScale * SelectFieldComponent(FIELD2, yComponent, &k);
  508.     z = zScale * SelectFieldComponent(FIELD3, zComponent, &k);
  509.     curveSeg[3][0] = x;
  510.     curveSeg[3][1] = y;
  511.     curveSeg[3][2] = z;
  512.  
  513.     for (k = 1; k < nSamples; ++k)
  514.     {
  515.         crv(curveSeg);
  516.  
  517.         /*Shift everything down and add new point*/
  518.         curveSeg[0][0] = curveSeg[1][0];
  519.         curveSeg[0][1] = curveSeg[1][1];
  520.         curveSeg[0][2] = curveSeg[1][2];
  521.         curveSeg[1][0] = curveSeg[2][0];
  522.         curveSeg[1][1] = curveSeg[2][1];
  523.         curveSeg[1][2] = curveSeg[2][2];
  524.         curveSeg[2][0] = curveSeg[3][0];
  525.         curveSeg[2][1] = curveSeg[3][1];
  526.         curveSeg[2][2] = curveSeg[3][2];
  527.  
  528.         if (k < nSamples - 1)
  529.         {
  530.         curveSeg[3][0] = xScale * SelectFieldComponent(FIELD1, xComponent, &k);
  531.         curveSeg[3][1] = yScale * SelectFieldComponent(FIELD2, yComponent, &k);
  532.         curveSeg[3][2] = zScale * SelectFieldComponent(FIELD3, zComponent, &k);
  533.         }
  534.     }
  535.  
  536.     /*Draw the hilited segments*/
  537.     SetUIColor(UIRED);
  538.     SetLineWidth(3);
  539.  
  540.     b = hiliteSegment - NSEGMENTS;
  541.     e = hiliteSegment;
  542.     if (b < 0) b = 0;
  543.     if (e >= nSamples) e = nSamples - 1;
  544.         
  545.     if (b > 0)
  546.     {
  547.         k = b - 1;
  548.  
  549.         x = xScale * SelectFieldComponent(FIELD1, xComponent, &k);
  550.         y = yScale * SelectFieldComponent(FIELD2, yComponent, &k);
  551.         z = zScale * SelectFieldComponent(FIELD3, zComponent, &k);
  552.  
  553.         curveSeg[0][0] = x;
  554.         curveSeg[0][1] = y;
  555.         curveSeg[0][2] = z;
  556.         ++k;
  557.     }
  558.     else
  559.     {
  560.         k = b;
  561.         x = xScale * SelectFieldComponent(FIELD1, xComponent, &k);
  562.         y = yScale * SelectFieldComponent(FIELD2, yComponent, &k);
  563.         z = zScale * SelectFieldComponent(FIELD3, zComponent, &k);
  564.  
  565.         curveSeg[0][0] = x;
  566.         curveSeg[0][1] = y;
  567.         curveSeg[0][2] = z;
  568.     }
  569.     x = xScale * SelectFieldComponent(FIELD1, xComponent, &k);
  570.     y = yScale * SelectFieldComponent(FIELD2, yComponent, &k);
  571.     z = zScale * SelectFieldComponent(FIELD3, zComponent, &k);
  572.     curveSeg[1][0] = x;
  573.     curveSeg[1][1] = y;
  574.     curveSeg[1][2] = z;
  575.     
  576.     ++k;
  577.     x = xScale * SelectFieldComponent(FIELD1, xComponent, &k);
  578.     y = yScale * SelectFieldComponent(FIELD2, yComponent, &k);
  579.     z = zScale * SelectFieldComponent(FIELD3, zComponent, &k);
  580.     curveSeg[2][0] = x;
  581.     curveSeg[2][1] = y;
  582.     curveSeg[2][2] = z;
  583.  
  584.     ++k;
  585.     x = xScale * SelectFieldComponent(FIELD1, xComponent, &k);
  586.     y = yScale * SelectFieldComponent(FIELD2, yComponent, &k);
  587.     z = zScale * SelectFieldComponent(FIELD3, zComponent, &k);
  588.     curveSeg[3][0] = x;
  589.     curveSeg[3][1] = y;
  590.     curveSeg[3][2] = z;
  591.     for (k = b + 1; k < e; ++k)
  592.     {
  593.         crv(curveSeg);
  594.  
  595.         /*Shift everything down and add new point*/
  596.         curveSeg[0][0] = curveSeg[1][0];
  597.         curveSeg[0][1] = curveSeg[1][1];
  598.         curveSeg[0][2] = curveSeg[1][2];
  599.         curveSeg[1][0] = curveSeg[2][0];
  600.         curveSeg[1][1] = curveSeg[2][1];
  601.         curveSeg[1][2] = curveSeg[2][2];
  602.         curveSeg[2][0] = curveSeg[3][0];
  603.         curveSeg[2][1] = curveSeg[3][1];
  604.         curveSeg[2][2] = curveSeg[3][2];
  605.  
  606.         if (k < nSamples - 1)
  607.         {
  608.         x = xScale * SelectFieldComponent(FIELD1, xComponent, &k);
  609.         y = yScale * SelectFieldComponent(FIELD2, yComponent, &k);
  610.         z = zScale * SelectFieldComponent(FIELD3, zComponent, &k);
  611.         curveSeg[3][0] = x;
  612.         curveSeg[3][1] = y;
  613.         curveSeg[3][2] = z;
  614.         }
  615.     }
  616.     }
  617.     else
  618.     {
  619.     /*Draw the unhilited segments*/
  620.     long b, e;
  621.  
  622.     SetUIColor(WHITE);
  623.     SetLineWidth(1);
  624.     k = 0;
  625.     x = xScale * SelectFieldComponent(FIELD1, xComponent, &k);
  626.     y = yScale * SelectFieldComponent(FIELD2, yComponent, &k);
  627.     z = zScale * SelectFieldComponent(FIELD3, zComponent, &k);
  628.     move(x, y, z);
  629.  
  630.     for (k = 1; k < nSamples; ++k)
  631.     {
  632.         x = xScale * SelectFieldComponent(FIELD1, xComponent, &k);
  633.         y = yScale * SelectFieldComponent(FIELD1, yComponent, &k);
  634.         z = zScale * SelectFieldComponent(FIELD1, zComponent, &k);
  635.         draw(x, y, z);
  636.     }
  637.  
  638.     SetUIColor(UIRED);
  639.     SetLineWidth(3);
  640.  
  641.     /*Draw the hilited segments*/
  642.     b = hiliteSegment - NSEGMENTS;
  643.     e = hiliteSegment;
  644.     if (b < 0) b = 0;
  645.     if (e >= nSamples) e = nSamples - 1;
  646.  
  647.     x = xScale * SelectFieldComponent(FIELD1, xComponent, &b);
  648.     y = yScale * SelectFieldComponent(FIELD2, yComponent, &b);
  649.     z = zScale * SelectFieldComponent(FIELD3, zComponent, &b);
  650.     move(x, y, z);
  651.         
  652.     for (k = b + 1; k <= e; ++k)
  653.     {
  654.         x = xScale * SelectFieldComponent(FIELD1, xComponent, &k);
  655.         y = yScale * SelectFieldComponent(FIELD1, yComponent, &k);
  656.         z = zScale * SelectFieldComponent(FIELD1, zComponent, &k);
  657.         draw(x, y, z);
  658.     }
  659.     }
  660.     SetLineWidth(1);
  661.     SetUIColor(UIGRAY50);
  662.     EndMask();
  663. #endif
  664.     return ObjTrue;
  665. }
  666.  
  667. #endif
  668.  
  669. void InitTraces()
  670. /*Initializes the traces*/
  671. {
  672. #ifndef RELEASE
  673.     ObjPtr icon;
  674.  
  675.     /*Class for a trace displayer*/
  676.     traceClass = NewObject(visColored, 0);
  677.     AddToReferenceList(traceClass);
  678.     SetVar(traceClass, NAME, NewString("Trace"));
  679.     SetMethod(traceClass, BOUNDS, MakeTraceBounds);
  680.     SetMethod(traceClass, ADDCONTROLS, AddTraceControls);
  681.     SetMethod(traceClass, SETMAINDATASET, SetTraceMainDataset);
  682.     SetMethod(traceClass, INITIALIZE, InitTrace);
  683.     icon = NewIcon(0, 0, ICONTRACE , "Trace");
  684.     SetVar(icon, HELPSTRING,
  685.     NewString("Select this icon to show controls for a trace, such \
  686. as whether to smooth the trace and show a moving trace."));
  687.     SetVar(traceClass, CONTROLICON, icon);
  688.     icon = NewObject(visIcon, 0);
  689.     SetVar(icon, WHICHICON, NewInt(ICONTRACE));
  690.     SetVar(icon, NAME, NewString("Trace"));
  691.     SetVar(icon, HELPSTRING,
  692.     NewString("This icon represents a trace object.  A trace object shows \
  693. a 1-D vector field as a trace in 3-space, taking the x, y, and z positions \
  694. from components of the vector."));
  695.  
  696.     SetVar(traceClass, DEFAULTICON, icon);
  697.     SetMethod(traceClass, DRAW, DrawTrace);
  698.     SetMethod(traceClass, WAKEUP, WakeTrace);
  699.  
  700. /*    DefineVisMapping(DS_HASFORM | DS_HASFIELD, 1, -1, -1, traceClass);
  701.     DefineVisMapping(DS_HASFIELD, 1, -1, -1, traceClass);
  702. */
  703.     DefineVisMapping(DS_HASFORM | DS_HASFIELD | DS_VECTOR, 1, -1, -1, traceClass);
  704.     DefineVisMapping(DS_HASFIELD | DS_VECTOR, 1, -1, -1, traceClass);
  705. #endif
  706. }
  707.  
  708. void KillTraces()
  709. /*Kills the traces*/
  710. {
  711. #ifndef RELEASE
  712.     DeleteThing(traceClass);
  713. #endif
  714. }
  715.